home *** CD-ROM | disk | FTP | other *** search
- /* macmpack.c -- Mac user interface to mpack routines
- *
- * (C) Copyright 1993-1995 by Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Carnegie Mellon University
- * not be used in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission. Carnegie
- * Mellon University makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
- * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
- * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- *
- * NOTE: a good GUI requires a lot of work... This needs more.
- */
-
- #include <Folders.h>
- #include <Script.h>
- #include <GestaltEqu.h>
-
- #include <stdio.h>
- #include <time.h>
- #include <string.h>
- #include <ctype.h>
- #include "version.h"
- #include "part.h"
- #include "macnapp.h"
- #include "macmpack.h"
- #include "macICTypes.h"
- #include "macICAPI.h"
- #include "macICKeys.h"
-
- /* ThinkC's internal stdio functions: */
- #include <ansi_private.h>
-
- /* window types: */
- #define DECODELIST 1
- #define PREFWIN 2
-
- /* save watch cursor */
- Cursor watch;
-
- /* preferences */
- struct pref_folder *pfolder = NULL;
- struct mpack_preferences **mpack_prefs = NULL;
- static ICInstance icinst = NULL;
-
- /* flag for active help window */
- static WindowPtr helpw = NULL;
-
- /* active decode status window */
- static na_win *curstatwin = NULL;
- short didchat;
-
- /* MacTCP started: -1 = error, 1 = active, 0 = unknown */
- static short tcpstart = 0;
-
- /* this is used for opening TEXT files */
- SFTypeList textList = { 'TEXT', 0, 0, 0 };
-
- /* next two types are used in the dialog used to select files to decode
- */
- typedef struct filelist {
- short vRefNum;
- long dirID;
- PCstr fname[65];
- } filelist;
- typedef struct listwin {
- na_win win;
- int count;
- filelist **hflist;
- ListHandle l;
- } listwin;
-
- /* this is the status window for decoding
- */
- typedef struct statuswin {
- na_win win;
- RgnHandle urgn; /* user region */
- Rect urect; /* user rectangle */
- Rect frect; /* frame rectangle */
- short row; /* row at top of scroll area */
- short nrow; /* rows of status text */
- long size, used; /* bytes of status text & amount used */
- Handle text; /* status text */
- ControlHandle sb; /* scroll bar control */
- short height, ascent; /* font height and ascent */
- } statuswin;
-
- /* this is for the encode window
- */
- typedef struct encodewin {
- nate_win w;
- Boolean nateon; /* cursor in Desc edit field */
- Boolean useemail; /* sending email */
- long partsize; /* max part size (0 = no limit) */
- OSType ftype; /* type of file to encode */
- FSSpec fspec; /* file to encode */
- FSSpec ofile; /* output file */
- } encodewin;
-
- /* show progress
- */
- typedef struct progresswin {
- natcp_win w;
- short percent;
- } progresswin;
-
- /* send mail
- */
- typedef struct mailwin {
- progresswin w;
- Handle headers; /* email headers */
- Handle envelope; /* envelope */
- short state; /* state */
- short remaining; /* messages remaining */
- Boolean sending; /* flag for active SMTP task */
- Boolean useemail; /* sending email */
- Boolean gothost; /* got the hostname */
- long partsize; /* max part size (0 = no limit) */
- long dirID; /* ID for temp dir */
- OSType ftype; /* type of file to encode */
- FSSpec fspec; /* file to be encoded */
- FSSpec ofile; /* output file */
- FILE *dfile; /* desc file */
- PCstr server[257]; /* SMTP server */
- PCstr subj[257]; /* subject */
- CInfoPBRec cpb;
- } mailwin;
-
- /* mailwin states */
- #define MS_MACTCP 0 /* Starting MacTCP */
- #define MS_GETHOST 1 /* Getting hostname */
- #define MS_ENCODE 2 /* Do encoding */
- #define MS_SENDING 3 /* Sending email */
-
- /* some prototypes */
- void warn(char *str);
- void stattext(Str255, unsigned char);
- static void do_decodefiles(na_win *);
- static void addfile(listwin *, FSSpec *);
- static void removefile(listwin *);
- static short listclose(na_win *);
- static short listmouse(na_win *, Point, short, short);
- static short listctrl(na_win *, Point, short, short, ControlHandle);
- static short listupdate(na_win *, Boolean);
- static short listinit(na_win *,long *);
- static short prefsctrl(na_win *, Point, short, short, ControlHandle);
- static short prefsinit(na_win *, long *);
- static void do_decode(FSSpec *);
- static void do_encode(FSSpec *, OSType);
- static short mainmenu(struct na_win*, WORD, WORD);
-
- #define dwin ((listwin *) win)
- #define swin ((statuswin *) win)
- #define ewin ((encodewin *) win)
- #define twin ((nate_win *) win)
- #define prwin ((progresswin *) win)
- #define mwin ((mailwin *) win)
-
- /* Get a FILE* to a Macintosh file
- ******************************* ###############################
- * KLUDGE ALERT! KLUDGE ALERT! * # KLUDGE ALERT! KLUDGE ALERT! #
- ******************************* ###############################
- * Mac files are specified by name/vRefNum/dirID combo, but the portable
- * portions of mpack use FILE* to do I/O. We need a way to get an open FILE*
- * from a file specified by name/vRefNum/dirID. Here we use the proper Macintosh
- * routines to open a file, then hack together a FILE* using ThinkC's internal
- * routines. The major trouble is that we have no way to get at the FILE action
- * procedure (fp->proc), so we need a sample FILE* to be passed in. Bleargh!
- ******************************* ###############################
- * KLUDGE ALERT! KLUDGE ALERT! * # KLUDGE ALERT! KLUDGE ALERT! #
- ******************************* ###############################
- */
- FILE *Macopen(FILE *sample, Str255 name, short vRefNum, long dirID,
- short binary_flag, short res_fork, SignedByte permission)
- {
- FILE *fp = NULL;
- short refnum;
- long curEOF;
- OSErr err;
-
- if ((!res_fork && (err = HOpen(vRefNum, dirID, name, permission, &refnum)) == noErr)
- || (res_fork && (err = HOpenRF(vRefNum, dirID, name, permission, &refnum)) == noErr)) {
- if ((fp = __getfile()) == NULL) {
- FSClose(refnum);
- } else {
- if (permission == fsWrPerm) {
- /* if we're writing to the file, truncate it */
- SetEOF(refnum, curEOF = 0);
- } else {
- GetEOF(refnum, &curEOF);
- }
- fp->refnum = refnum;
- fp->len = (fpos_t) curEOF;
- fp->binary = binary_flag;
- setvbuf(fp, NULL, _IOFBF, BUFSIZ);
- fp->proc = sample->proc;
- }
- }
-
- return (fp);
- }
-
-
- /* warn the user
- */
- void warn(char *str)
- {
- PCstr wstr[257];
-
- CtoPCstrncpy(wstr, str, 255);
- ParamText(P(wstr), NULL, NULL, NULL);
- NAalert(warnALRT);
- }
-
- /* yell at the user
- */
- void yell(char *str)
- {
- PCstr wstr[257];
-
- CtoPCstrncpy(wstr, str, 255);
- ParamText(P(wstr), NULL, NULL, NULL);
- NAalert(errorALRT);
- }
-
- /* chat with user
- */
- chat(char *str)
- {
- PCstr tmpstr[257];
-
- CtoPCstrcpy(tmpstr, str);
- stattext(P(tmpstr), 0);
- }
-
- /* returns NA_ALLCLOSED if appropriate, else NA_CLOSED
- */
- static short alldone(na_win *win)
- {
- if (win->next == NULL && win->afterp == NULL && (*mpack_prefs)->quit_finished
- && RecoverHandle((Ptr) win) == (Handle) NAhead) {
- return (NA_ALLCLOSED);
- }
-
- return (NA_CLOSED);
- }
-
- /* update procedure for status dialog box
- */
- static short statupdate(na_win *win, Boolean newsize)
- {
- RgnHandle savergn;
- unsigned char *s;
- short row, top;
- Rect tmpr;
-
- FrameRect(&swin->frect);
- savergn = NewRgn();
- if (savergn) {
- GetClip(savergn);
- SetClip(swin->urgn);
- }
-
- /* redraw text area */
- HLock(swin->text);
- s = * (unsigned char **) swin->text;
- top = swin->urect.top;
- for (row = 0; row < swin->row; ++row) {
- s += s[1] + 2;
- }
- for (; row < swin->nrow && top + swin->height <= swin->urect.bottom; ++row) {
- MoveTo(swin->urect.left, top + swin->ascent);
- if (*s) TextFace(1);
- DrawString(s + 1);
- if (*s) TextFace(0);
- /* advance to next string */
- top += swin->height;
- s += s[1] + 2;
- }
- HUnlock(swin->text);
-
- if (savergn) {
- SetClip(savergn);
- DisposeRgn(savergn);
- }
-
- return (NA_NOTPROCESSED);
- }
-
- /* refresh status window
- */
- void statrefresh()
- {
- na_win *win = curstatwin;
-
- Draw1Control(swin->sb);
- statupdate(win, false);
- }
-
- /* add text to the status window
- */
- void stattext(Str255 str, unsigned char bold)
- {
- na_win *win = curstatwin;
- short i, len;
- unsigned char *s, *start;
- RgnHandle rgn;
- Rect tmpr;
-
- if (!win) return;
- didchat = 1;
-
- /* advance to next row */
- if (swin->height * (swin->nrow++ - swin->row)
- >= swin->urect.bottom - swin->urect.top) {
- SetCtlMax(swin->sb, ++swin->row);
- SetCtlValue(swin->sb, swin->row);
- if ((rgn = NewRgn()) != NULL) {
- tmpr = swin->urect;
- ScrollRect(&tmpr, 0, -swin->height, rgn);
- DisposeRgn(rgn);
- }
- }
-
- /* add the text */
- len = * (unsigned char *) str;
- if (swin->size - swin->used < len + 1) {
- SetHandleSize(swin->text, swin->size * 2);
- if (MemError() == 0) swin->size *= 2;
- }
- HLock(swin->text);
- s = start = * (unsigned char **) swin->text;
- for (i = 1; i < swin->nrow; ++i) {
- s += s[1] + 2;
- }
- if (len + 2 + s < start + swin->size) {
- *s = bold;
- memcpy(s + 1, str, len + 1);
- swin->used = s + len + 2 - start;
- }
- HUnlock(swin->text);
- statupdate(win, false);
- }
-
- /* scroll the status dialog
- */
- static void statscroll(na_win *win, short rows)
- {
- RgnHandle rgn;
-
- if ((rgn = NewRgn()) != NULL) {
- SetCtlValue(swin->sb, swin->row += rows);
- ScrollRect(&swin->urect, 0, - swin->height * rows, rgn);
- EraseRgn(rgn);
- DisposeRgn(rgn);
- }
- statupdate(win, false);
- }
-
- /* scroll bar procedure
- */
- static pascal void statscollbar(ControlHandle ctrlh, short part)
- {
- na_win *win = (na_win *) GetCRefCon(ctrlh);
- short max, new, page;
-
- max = GetCtlMax(ctrlh);
- page = (swin->urect.bottom - swin->urect.top) / swin->height - 1;
- switch (part) {
- case inUpButton:
- page = 1;
- /* fall through */
- case inPageUp:
- if (swin->row > 0) {
- statscroll(win, - (swin->row < page ? swin->row : page));
- }
- break;
- case inDownButton:
- page = 1;
- /* fall through */
- case inPageDown:
- if (swin->row < max) {
- statscroll(win, max - swin->row < page ? max - swin->row : page);
- }
- break;
- case inThumb:
- break;
- }
- }
-
- /* control procedure for status dialog box
- */
- static short statctrl(na_win *win, Point p, short item, short mods, ControlHandle ctrlh)
- {
- short value;
-
- if (ctrlh == swin->sb) {
- ctrlh = swin->sb;
- if (item != inThumb) {
- SetCRefCon(ctrlh, (long) win);
- TrackControl(ctrlh, p, statscollbar);
- } else {
- TrackControl(ctrlh, p, nil);
- value = GetCtlValue(ctrlh);
- if (value != swin->row) statscroll(win, value - swin->row);
- }
- } else if (item == iOk) {
- return (NA_REQCLOSE);
- }
-
- return (NA_NOTPROCESSED);
- }
-
- /* close procedure for status dialog box
- */
- static short statclose(na_win *win)
- {
- DisposeRgn(swin->urgn);
- DisposHandle(swin->text);
- DisposeControl(swin->sb);
-
- return (alldone(win));
- }
-
- /* init procedure for status dialog box
- */
- static short statinit(na_win *win, long *data)
- {
- Rect tmpr;
- FontInfo finfo;
-
- /* disable OK button while working */
- NAhiliteDItem(win->pwin, iOk, 255);
-
- /* set up status text area & font */
- if ((swin->urgn = NewRgn()) == NULL) return (NA_CLOSED);
- TextFont(geneva);
- TextSize(9);
- GetFontInfo(&finfo);
- swin->ascent = finfo.ascent;
- swin->height = finfo.ascent + finfo.descent + finfo.leading;
- NAgetDRect(win->pwin, iStatus, &swin->frect);
- swin->urect = swin->frect;
- InsetRect(&swin->urect, 2,
- 2 + ((swin->urect.bottom - swin->urect.top - 4) % swin->height) / 2);
- RectRgn(swin->urgn, &swin->urect);
-
- /* set up text storage */
- if ((swin->text = NewHandle(swin->size = 1024)) == NULL) {
- DisposeRgn(swin->urgn);
- return (NA_CLOSED);
- }
- **(char **)swin->text = '\0';
-
- /* set up scrollbar */
- NAgetDRect(win->pwin, iStatScroll, &tmpr);
- swin->sb = NewControl(win->pwin, &tmpr, "\p", true, 0, 0, 0, scrollBarProc, 0);
- if (!swin->sb) {
- DisposeRgn(swin->urgn);
- DisposHandle(swin->text);
- return (NA_CLOSED);
- }
-
- /* set up procedures */
- win->closep = statclose;
- win->ctrlp = statctrl;
- win->updatep = statupdate;
-
- /* keep window locked until decoding is done */
- ++win->locks;
- curstatwin = win;
-
- return (NA_NOTPROCESSED);
- }
-
- /* process the files in the file list
- */
- static void do_decodefiles(na_win *win)
- {
- int count = dwin->count;
- filelist *fl;
- FILE *dfile, *tmpf;
- extern long _ftype, _fcreator;
- long ticks;
- int result;
-
- MapTypeCreator("text/plain", 0);
- SetCursor(&watch);
- if (NAwindow(0, NA_DIALOGWINDOW | NA_TITLEBAR | NA_DEFBUTTON | NA_USERESOURCE
- | NA_CLOSEBOX | NA_HASCONTROLS,
- 0, dstatDLOG, 0, sizeof (statuswin), statinit) == NA_CLOSED) {
- warn("Not enough memory to decode");
- return;
- }
- MoveHHi((Handle) dwin->hflist);
- HLock((Handle) dwin->hflist);
- fl = *dwin->hflist;
- tmpf = tmpfile();
- while (count--) {
- stattext(fl->fname, 1);
- didchat = 0;
- if (dfile = Macopen(tmpf, fl->fname, fl->vRefNum, fl->dirID, 0, 0, 1)) {
- result = handleMessage(part_init(dfile), "text/plain",
- 0, (*mpack_prefs)->extract_text);
- if (result != 0 || didchat <= 0) {
- if (didchat < 0) {
- chat("Decoding cancelled");
- } else {
- chat("Found nothing to decode");
- }
- }
- fclose(dfile);
- } else {
- chat("Couldn't find source file");
- }
- ++fl;
- }
- fclose(tmpf);
- HUnlock((Handle) dwin->hflist);
- NAhiliteDItem(curstatwin->pwin, iOk, 0);
- NAunlockWindow(curstatwin);
- curstatwin = NULL;
- SetCursor(&arrow);
- DisposHandle((Handle) dwin->hflist);
- }
-
- /* return non-zero if two filenames have the same prefix
- */
- static int fprefixMatch(char *base, PCstr *match)
- {
- PCstr temp[257];
- char *scan;
- short prefixlen;
-
- PtoPCstrcpy(temp, base);
- scan = C(temp) + PCstrlen(temp) - 1;
- while (isdigit(*scan) && scan > C(temp)) --scan;
- prefixlen = scan - C(temp) + 1;
- if (strncmp(C(temp), C(match), prefixlen)) return (0);
- scan = C(match) + prefixlen;
- while (isdigit(*scan)) ++scan;
-
- return (!*scan);
- }
-
- /* do the add of a file to a list
- */
- static void addit(listwin *dw, short vRefNum, long dirID, char *fname)
- {
- long size = GetHandleSize((Handle) dw->hflist) / sizeof (filelist);
- filelist *fl;
- char *bp;
- Cell c;
- int i;
- PCstr fbuf[42];
-
- if (size == dw->count) {
- SetHandleSize((Handle) dw->hflist, (++size * sizeof (filelist)));
- if (MemError() != noErr) return;
- }
- MoveHHi((Handle) dw->hflist);
- HLock((Handle) dw->hflist);
- fl = *dw->hflist;
- for (i = dw->count; i; --i, ++fl) {
- if (fl->vRefNum == vRefNum && fl->dirID == dirID &&
- *fl->fname == *fname && !strncmp(C(fl->fname), C(fname), *fl->fname)) {
- break;
- }
- }
- if (!i) {
- fl->vRefNum = vRefNum;
- fl->dirID = dirID;
- PtoPCstrcpy(fl->fname, fname);
- SetPt(&c, 0, dw->count);
- LAddRow(1, ++dw->count, dw->l);
- LSetCell((Ptr) C(fname), (short) Pstrlen(fname), c, dw->l);
- }
- HUnlock((Handle) dw->hflist);
- }
-
- /* add file set to file list
- */
- static void addfile(dw, fspec)
- listwin *dw;
- FSSpec *fspec;
- {
- CInfoPBRec cipbr;
- HFileInfo *fpb = (HFileInfo *)&cipbr;
- PCstr fbuf[42];
- short idx, foundone = 0;
- long procid;
-
- /* remove working directory stuff */
- if (fspec->parID == 0) {
- GetWDInfo(fspec->vRefNum, &fspec->vRefNum, &fspec->parID, &procid);
- }
-
- /* loop through directory */
- for (idx = 1; ; ++idx) {
- fpb->ioVRefNum = fspec->vRefNum;
- fpb->ioNamePtr = P(fbuf);
- fpb->ioDirID = fspec->parID;
- fpb->ioFDirIndex = idx;
- if (PBGetCatInfoSync(&cipbr)) break;
- SetClen(fbuf);
-
- if (!(fpb->ioFlAttrib & 16) && fprefixMatch((char *)fspec->name, fbuf)) {
- addit(dw, fspec->vRefNum, fspec->parID, (char *) P(fbuf));
- foundone = 1;
- }
- }
- if (!foundone) {
- addit(dw, fspec->vRefNum, fspec->parID, (char *) fspec->name);
- }
- }
-
- /* remove file from file list
- */
- static void removefile(dw)
- listwin *dw;
- {
- filelist *fl;
- int count;
- Cell c;
-
- c.h = c.v = 0;
- if (LGetSelect(TRUE, &c, dw->l)) {
- MoveHHi((Handle) dw->hflist);
- HLock((Handle) dw->hflist);
- fl = *dw->hflist + c.v;
- count = dw->count - c.v;
- while (--count) {
- fl[0] = fl[1];
- ++fl;
- }
- HUnlock((Handle) dw->hflist);
- --dw->count;
- LDelRow(1, c.v, dw->l);
- }
- }
-
- /* close list window
- */
- static short listclose(win)
- na_win *win;
- {
- LDispose(dwin->l);
-
- return (alldone(win));
- }
-
- /* mouse procedure
- */
- static short listmouse(na_win *win, Point p, short type, short mods)
- {
- Cell c;
-
- if (!(type & 1)) {
- LClick(p, mods, dwin->l);
- c.h = c.v = 0;
- NAhiliteDItem((DialogPtr)win->pwin, iRemove, LGetSelect(TRUE, &c, dwin->l) ? 0 : 255);
- }
-
- return (NA_NOTPROCESSED);
- }
-
- /* control procedure
- */
- static short listctrl(na_win *win, Point p, short item, short mods, ControlHandle ctrlh)
- {
- StandardFileReply reply;
-
- switch (item) {
- case iAdd:
- NAgetFile(NULL, 1, textList, &reply);
- if (reply.sfGood) {
- if (!dwin->count) {
- NAhiliteDItem((DialogPtr)win->pwin, iOk, 0);
- }
- addfile(dwin, &reply.sfFile);
- }
- return (NA_PROCESSED);
-
- case iRemove:
- removefile(dwin);
- NAhiliteDItem((DialogPtr)win->pwin, iRemove, 255);
- if (!dwin->count) {
- NAhiliteDItem((DialogPtr)win->pwin, iOk, 255);
- }
- return (NA_PROCESSED);
-
- case iOk:
- win->afterp = do_decodefiles;
- case iCancel:
- return (NA_REQCLOSE);
- }
-
- return (NA_NOTPROCESSED);
- }
-
- /* update the list window
- */
- static short listupdate(na_win *win, Boolean resize)
- {
- Rect r;
-
- NAgetDRect(win->pwin, iFileList, &r);
- FrameRect(&r);
- LUpdate(win->pwin->visRgn, dwin->l);
-
- return (NA_NOTPROCESSED);
- }
-
- /* initialize the list window
- */
- static short listinit(win, data)
- na_win *win;
- long *data;
- {
- FSSpec *fspec = (FSSpec *) data;
- Rect r, zrect;
- Point p;
- Handle hand;
- short type;
-
- GetDItem((DialogPtr)win->pwin, iFileList, &type, &hand, &r);
- InsetRect(&r, 1, 1);
- zrect.top = zrect.bottom = zrect.left = p.h = p.v = 0;\
- zrect.right = 1;
- dwin->l = LNew(&r, &zrect, p, 0, win->pwin, 0, 0, 0, 1);
- if (!dwin->l) return (NA_CLOSED);
- (*dwin->l)->selFlags = lOnlyOne;
- dwin->hflist = (filelist **) NewHandle(sizeof (filelist));
- if (!dwin->hflist) {
- LDispose(dwin->l);
- return (NA_CLOSED);
- }
- dwin->count = 0;
- addfile(dwin, fspec);
- win->closep = listclose;
- win->updatep = listupdate;
- win->ctrlp = listctrl;
- win->mousep = listmouse;
- win->type = DECODELIST;
- NAhiliteDItem((DialogPtr)win->pwin, iRemove, 255);
- ShowWindow(win->pwin);
- LDoDraw(TRUE, dwin->l);
-
- return (NA_NOTPROCESSED);
- }
-
- /* Decode procedure: first get a file, then open decode window
- */
- static void do_decode(FSSpec *fspec)
- {
- StandardFileReply infile;
- na_win **wh, *wp;
-
- if (!fspec) {
- NAgetFile(NULL, 1, textList, &infile);
- if (!infile.sfGood) return;
- fspec = &infile.sfFile;
- } else {
- /* file supplied by drag & drop, look for existing decode window: */
- for (wh = NAhead; wh && (*wh)->type != DECODELIST; wh = (*wh)->next);
- if (wh && (wp = NAlockWindow(wh)) != NULL) {
- addfile((listwin *) wp, fspec);
- NAunlockWindow(wp);
- return;
- }
- }
- NAwindow(0, NA_DIALOGWINDOW | NA_USERESOURCE | NA_DEFBUTTON |
- NA_HASCONTROLS | NA_CLOSEBOX, NULL, decodeDLOG, (long *) fspec,
- sizeof (listwin), listinit);
- }
-
- /* Map MIME type to/from Macintosh file types
- */
- void MapTypeCreator(char *contenttype, OSType type)
- {
- extern long _ftype, _fcreator;
- PCstr tstr[257];
- Handle h;
- ICAttr attr;
- long size = 0;
- Ptr map;
- ICMapEntry *ment;
- unsigned char *scan, *end, *pstr;
- short mapcount, i, foundit = 0;
- OSType temp;
-
- if (!type) CtoPCstrncpy(tstr, contenttype, 255);
-
- /* first try a lookup via Internet Config */
- if (icinst && ICBegin(icinst, icReadOnlyPerm) == noErr) {
- if (ICGetPref(icinst, kICMapping, &attr, nil, &size) == noErr
- && size > 0 && (map = NewPtr(size)) != nil) {
- if (ICGetPref(icinst, kICMapping, &attr, map, &size) == noErr) {
- scan = (unsigned char *) map;
- end = scan + size;
- while (scan < end) {
- ment = (ICMapEntry *) scan;
- pstr = scan + ment->fixed_length;
- scan += ment->total_length;
- if (type && ment->file_type != type) continue;
- pstr += *pstr + 1; /* skip over extension */
- pstr += *pstr + 1; /* skip over creator app name */
- pstr += *pstr + 1; /* skip over post app name */
- if (type) {
- PtoPCstrcpy((PCstr *) contenttype, (char *) pstr);
- foundit = 1;
- break;
- } else if (EqualString(P(tstr), pstr, false, true)) {
- _ftype = ment->file_type;
- _fcreator = ment->file_creator;
- foundit = 1;
- break;
- }
- }
- }
- DisposPtr(map);
- }
- ICEnd(icinst);
- }
-
- /* if we didn't find it, try our quick&dirty mappings */
- if (!foundit) {
- if (type) {
- mapcount = CountResources('TyCr');
- for (i = 1; i <= mapcount; ++i) {
- h = GetIndResource('TyCr', i);
- if (h && **(OSType **)h == type) {
- GetResInfo(h, &i, &temp, P(contenttype));
- if (ResError() == noErr) break;
- }
- }
- SetClen((PCstr *) contenttype);
- } else {
- h = GetNamedResource('TyCr', P(tstr));
- if (h) {
- _ftype = (*(OSType **)h)[0];
- _fcreator = (*(OSType **)h)[1];
- } else {
- _ftype = '????';
- _fcreator = 'mPAK';
- }
- }
- }
- }
-
- /* get internet config string prefs
- */
- static short getICprefs(na_win *win, PCstr *eaddr, PCstr *smtphost)
- {
- char *scan, *end;
- ICAttr attr;
- long size;
- ICError err = noErr;
-
- *C(eaddr) = '\0';
- SetPlen(eaddr);
- *C(smtphost) = '\0';
- SetPlen(smtphost);
- if (icinst && ICBegin(icinst, icReadOnlyPerm) == noErr) {
- size = 256;
- if (ICGetPref(icinst, kICEmail, &attr, (Ptr) eaddr, &size) == noErr
- && win && (attr & ICattr_locked_mask)) {
- NAenableDItem(win->pwin, iEmailAddr, 0);
- }
- SetClen(eaddr);
- size = 256;
- if (ICGetPref(icinst, kICSMTPHost, &attr, (Ptr) smtphost, &size) == noErr
- && win && (attr & ICattr_locked_mask)) {
- NAenableDItem(win->pwin, iMailServer, 0);
- }
- SetClen(smtphost);
- ICEnd(icinst);
- } else {
- HLock((Handle) mpack_prefs);
- end = (char *) (*mpack_prefs) + GetHandleSize((Handle) mpack_prefs);
- scan = (*mpack_prefs)->internet_host;
- while (scan < end && *scan++);
- if (scan < end) CtoPCstrcpy(eaddr, scan);
- while (scan < end && *scan++);
- if (scan < end) CtoPCstrcpy(smtphost, scan);
- HUnlock((Handle) mpack_prefs);
- }
- }
-
- /* copy desc file, with word-wrap
- */
- static short copydesc(FILE *out, TEHandle hTE)
- {
- char c;
- short i, count, word, col, reset;
- char **htxt;
-
- count = (*hTE)->teLength;
- htxt = (char **) (*hTE)->hText;
- for (i = word = col = 0; i < count; ++i) {
- c = (*htxt)[i];
- reset = i - word == 80 || c == '\r';
- if (reset || c == ' ') {
- while (word < i) putc((*htxt)[word], out), ++word;
- }
- if (reset || ++col == 80) {
- putc('\r', out);
- c = (*htxt)[word];
- if (c == ' ' || c == '\r') ++word;
- col = 0;
- }
- }
- while (word < i) putc((*htxt)[word], out), ++word;
- rewind(out);
- }
-
- /* start up MacTCP callback
- */
- static void mytcpinit(short status)
- {
- static DialogPtr dialog = NULL;
- GrafPtr save;
- Rect box;
-
- if (status < 0) {
- tcpstart = -1;
- } else if (status == 0) {
- tcpstart = 1;
- } else {
- if (!dialog && status < 100) {
- dialog = GetNewDialog(progDLOG, nil, (WindowPtr) -1);
- NAsetIText(dialog, iWorkText, "\pWaiting for MacTCP to finish. Press \021. to stop.");
- }
- if (dialog) {
- GetPort(&save);
- SetPort(dialog);
- NAgetDRect(dialog, iProgress, &box);
- FrameRect(&box);
- InsetRect(&box, 1, 1);
- box.right = box.left + (box.right - box.left) * status / 100;
- FillRect(&box, qd.dkGray);
- SetPort(save);
- if (status == 100) {
- DisposDialog(dialog);
- dialog = NULL;
- }
- }
- }
- }
-
- /* update the progress bar
- */
- static short progressupdate(na_win *win, Boolean newsize)
- {
- Rect box;
-
- if (prwin->percent >= 0) {
- NAgetDRect(win->pwin, iProgress, &box);
- FrameRect(&box);
- InsetRect(&box, 1, 1);
- if (prwin->percent) {
- box.right = box.left + (box.right - box.left) * prwin->percent / 100;
- FillRect(&box, qd.dkGray);
- } else {
- EraseRect(&box);
- }
- }
-
- return (NA_NOTPROCESSED);
- }
-
- /* handle the cancel button
- */
- static short progressctrl(na_win *win, Point p, short item, short mods,
- ControlHandle ctrlh)
- {
- return (item == iCancel ? NA_REQCLOSE : NA_NOTPROCESSED);
- }
-
- /* close progress window
- */
- static short progressclose(na_win *win)
- {
- NAmodalMenus(0);
-
- return (NA_CLOSED);
- }
-
- /* make/go directory under prefs and return directory number
- */
- static OSErr prefsubdir(PCstr *name, long *dirID)
- {
- CInfoPBRec cipbr;
- DirInfo *dpb = &cipbr.dirInfo;
- long subdir, dir;
- short vref = pfolder->fspec.vRefNum;
- OSErr err;
-
- err = DirCreate(vref, dir = pfolder->fspec.parID, P(name), &subdir);
- if (err == dupFNErr) {
- dpb->ioVRefNum = vref;
- dpb->ioNamePtr = P(name);
- dpb->ioDrDirID = dir;
- dpb->ioFDirIndex = 0;
- if ((err = PBGetCatInfoSync(&cipbr)) != noErr) return (err);
- subdir = dpb->ioDrDirID;
- } else if (err != noErr) {
- return (err);
- }
- *dirID = subdir;
-
- return (noErr);
- }
-
- /* smtp status task
- */
- static void smtpstat(void *wh, short code, short err, long num, char *errstr)
- {
- na_win *win, **winh;
- char msg[256];
- OSErr oserr = noErr;
-
- /* verify win is valid */
- for (winh = NAhead; winh && winh != wh; winh = (*winh)->next);
- if (!winh) return;
-
- /* handle SMTP callback */
- win = NAlockWindow((na_win **) wh);
- if (code == NASMTP_progress) {
- prwin->percent = err;
- progressupdate(win, false);
- } else if (code == NASMTP_badaddr) {
- sprintf(msg, "Invalid address: <%s>. Email will be sent to valid recipients.",
- errstr);
- yell(msg);
- } else {
- switch (code) {
- case NASMTP_nomem:
- yell("Not enough memory to send email");
- break;
- case NASMTP_tcpfail:
- yell("Failed to connect to mail host");
- break;
- case NASMTP_temperr:
- case NASMTP_permerr:
- sprintf(msg, "Delivery failed: %s", errstr);
- yell(msg);
- break;
- default:
- yell("Mail delivery failed.");
- case NASMTP_completed:
- break;
- }
- mwin->sending = false;
- oserr = HDelete(mwin->fspec.vRefNum, mwin->fspec.parID, mwin->fspec.name);
- }
- if (oserr != noErr && oserr != fnfErr) {
- if (mwin->remaining) ++mwin->cpb.hFileInfo.ioFDirIndex;
- yell("Unable to remove temporary email file.");
- }
- NAunlockWindowh((na_win **) wh, win);
- }
-
- /* Get the email hostname
- */
- static void mailhost(void *user, na_tcp s, short status, long size, char *data)
- {
- struct mpack_preferences *mp;
- char *ihost;
- na_win *win, **winh;
- long len, oldsize;
-
- /* first make sure our window still exists */
- for (winh = NAhead; winh && winh != user; winh = (*winh)->next);
- if (!winh) return;
- win = NAlockWindow(winh);
-
- /* check for errors */
- if (status != NATCP_connect) {
- warn("Failed to get hostname from MacTCP");
- } else {
- mwin->gothost = true;
- if (data[size - 1] == '.') --size;
-
- /* update internet_host preference */
- len = strlen((*mpack_prefs)->internet_host);
- oldsize = GetHandleSize((Handle) mpack_prefs);
- if (len < size) {
- SetHandleSize((Handle) mpack_prefs, oldsize + (size - len));
- if (MemError() != noErr) return;
- }
- HLock((Handle) mpack_prefs);
- mp = *mpack_prefs;
- ihost = mp->internet_host;
- memmove(ihost + size + 1, ihost + len + 1,
- oldsize - len - 1 - ((char *) ihost - (char *) mp));
- memcpy(ihost, data, size);
- ihost[size] = '\0';
- HUnlock((Handle) mpack_prefs);
- }
- NAunlockWindowh(winh, win);
- }
-
- /* clean up mail task
- */
- static short mailclose(na_win *win)
- {
- if (mwin->dfile != NULL) fclose(mwin->dfile);
- if (mwin->envelope) DisposeHandle(mwin->envelope);
- if (mwin->headers) DisposeHandle(mwin->headers);
- NAmodalMenus(0);
-
- return (alldone(win));
- }
-
- /* send email
- */
- static short mailtask(na_win *win)
- {
- short vrefnum, encoding, refnum, result;
- long procid;
- FILE *tmpf, *fp, *resfork;
- OSErr err;
- CInfoPBRec cipbr;
- HFileInfo *fpb = (HFileInfo *)&cipbr;
- PCstr tstr[257], mtype[257], fname[257];
- extern long _ftype, _fcreator;
-
- switch (mwin->state) {
- case MS_MACTCP:
- if (tcpstart < 0) {
- yell("Couldn't find MacTCP");
- return (NA_REQCLOSE);
- }
- if (tcpstart == 0) break;
- ++mwin->state;
- NAsetIText(win->pwin, iWorkText, "\pGetting Hostname");
- mwin->gothost = false;
- NATCPgethost(mailhost, (void *) GetWRefCon(win->pwin));
- /* fall through */
- case MS_GETHOST:
- if (!mwin->gothost) break;
- ++mwin->state;
- /* fall through */
- case MS_ENCODE:
- NAsetIText(win->pwin, iWorkText, "\pEncoding file");
-
- /* get temp output filename for email */
- if (mwin->useemail) {
- mwin->ofile.vRefNum = pfolder->fspec.vRefNum;
- memcpy(mwin->ofile.name, "\pemail", 6);
- if (prefsubdir("\poutgoing-email", &mwin->ofile.parID) != noErr) {
- yell("Failed to write encoded file");
- return (NA_REQCLOSE);
- }
- }
-
- /* set file type */
- SetCursor(&watch);
- MapTypeCreator((char *) mtype, mwin->ftype);
-
- /* Determine the correct encoding */
- encoding = (*mpack_prefs)->encoding;
- fpb->ioVRefNum = mwin->fspec.vRefNum;
- fpb->ioNamePtr = mwin->fspec.name;
- fpb->ioDirID = mwin->fspec.parID;
- fpb->ioFDirIndex = 0;
- if (PBGetCatInfoSync(&cipbr) != noErr) {
- SetCursor(&arrow);
- yell("File disappeared before being encoded!");
- return (NA_REQCLOSE);
- }
- if (encoding == EN_AUTO) {
- encoding = EN_DOUBLE;
- if (!fpb->ioFlRLgLen && *mtype != '\0') encoding = EN_DATA;
- }
- if (!fpb->ioFlLgLen) encoding = EN_SINGLE;
-
- /* do applesingle/appledouble encoding */
- tmpf = tmpfile();
- fp = Macopen(tmpf, mwin->fspec.name, mwin->fspec.vRefNum, mwin->fspec.parID,
- strcmp(C(mtype), "text/plain") ? 1 : 0, 0, fsRdPerm);
- if (!fp) {
- fclose(tmpf);
- SetCursor(&arrow);
- yell("Couldn't save encoded file");
- return (NA_REQCLOSE);
- }
- if (encoding == EN_DATA) {
- fclose(tmpf);
- tmpf = NULL;
- } else {
- /* open resource fork & output file for applesingle/double encoding */
- resfork = Macopen(tmpf, mwin->fspec.name, mwin->fspec.vRefNum,
- mwin->fspec.parID, 1, 1, 1);
- if (encode_applefile(tmpf, fpb, resfork, encoding == EN_SINGLE ? fp : NULL) < 0) {
- SetCursor(&arrow);
- yell("Couldn't save encoded file");
- return (NA_REQCLOSE);
- }
- rewind(tmpf);
- if (encoding == EN_SINGLE) {
- fp = tmpf;
- tmpf = NULL;
- strcpy(C(mtype), "application/applefile");
- SetPlen(mtype);
- }
- }
-
- /* generate output files */
- _fcreator = 'mPAK';
- _ftype = 'TEXT';
- GetVol(0, &vrefnum);
- err = OpenWD(mwin->ofile.vRefNum, mwin->ofile.parID, 0, &refnum);
- SetVol(0, err == noErr ? refnum : mwin->ofile.vRefNum);
- PtoPCstrcpy(tstr, (char *) mwin->ofile.name);
- PtoPCstrcpy(fname, (char *) mwin->fspec.name);
- result = encode(fp, tmpf, C(fname), mwin->dfile, C(mwin->subj), NULL,
- mwin->partsize, PCstrlen(mtype) ? C(mtype) : NULL, C(tstr));
- if (err == noErr) CloseWD(refnum);
- SetVol(0, vrefnum);
- if (tmpf) fclose(tmpf);
- fclose(fp);
- if (mwin->dfile) {
- fclose(mwin->dfile);
- mwin->dfile = NULL;
- }
- SetCursor(&arrow);
- if (!mwin->useemail) return (NA_REQCLOSE);
- prwin->percent = 0;
- progressupdate(win, false);
- ++mwin->state;
-
- /* count files */
- mwin->cpb.dirInfo.ioVRefNum = mwin->ofile.vRefNum;
- mwin->cpb.dirInfo.ioDrDirID = mwin->dirID = mwin->ofile.parID;
- mwin->cpb.dirInfo.ioFDirIndex = -1;
- if (PBGetCatInfoSync(&mwin->cpb) != noErr) {
- return (NA_CLOSED);
- }
- mwin->remaining = mwin->cpb.dirInfo.ioDrNmFls;
- mwin->cpb.dirInfo.ioFDirIndex = 1;
- /* fall through */
- case MS_SENDING:
- if (mwin->sending) break;
- if (!mwin->remaining) return (NA_REQCLOSE);
- sprintf(C(tstr), "Email parts remaining to submit: %d", mwin->remaining--);
- SetPlen(tstr);
- NAsetIText(win->pwin, iWorkText, tstr);
- prwin->percent = 0;
- progressupdate(win, false);
- mwin->cpb.hFileInfo.ioDirID = mwin->dirID;
- mwin->cpb.hFileInfo.ioNamePtr = (StringPtr) &mwin->fspec.name;
- if (PBGetCatInfoSync(&mwin->cpb) != noErr) {
- yell("Email disappeared before submission!");
- return (NA_REQCLOSE);
- }
- mwin->sending = true;
- mwin->fspec.vRefNum = mwin->cpb.hFileInfo.ioVRefNum;
- mwin->fspec.parID = mwin->dirID;
- NASMTPsubmit(smtpstat, C(mwin->server), &mwin->fspec,
- mwin->headers, mwin->envelope,
- NASMTP_crtrans, (void *) GetWRefCon(win->pwin));
- break;
- }
-
- return (NA_NOTPROCESSED);
- }
-
- /* Following routine stolen from Mark Crispin's c-client library:
- *
- * Write current time in RFC 822 format
- * Accepts: destination string
- *
- * This depends upon the ReadLocation() call in System 7 and the
- * user properly setting his location/timezone in the Map control
- * panel.
- * 2/95 - I added support for dlsDelta & compatibility checking
- */
- void rfc822_date(char *string)
- {
- long tz, tzm;
- time_t ti = time (0);
- struct tm *t = localtime (&ti);
- MachineLocation loc;
-
- /* output date */
- strcpy(string, "Date: ");
- string += 6;
- strftime (string,1024,"%a, %d %b %Y %H:%M:%S ",t);
- /* now output time zone, if we can get it */
- tz = 0;
- if (Gestalt(gestaltScriptMgrVersion, &tz) == noErr && tz >= 200) {
- ReadLocation(&loc); /* get location/timezone */
- /* get sign-extended time zone */
- tz = (loc.gmtFlags.gmtDelta & 0x00ffffff) |
- ((loc.gmtFlags.gmtDelta & 0x00800000) ? 0xff000000 : 0);
- tz /= 60; /* get timezone in minutes */
- tzm = tz % 60; /* get minutes from the hour */
- sprintf (string += strlen(string),"%+03ld%02ld",
- tz/60,tzm >= 0 ? tzm : -tzm);
- if (!tzm && tz <= -240 && tz >= -660) {
- string += strlen(string);
- if (loc.gmtFlags.dlsDelta & 0x80) {
- sprintf(string, " (%cDT)", "AECMPYHB"[- (tz / 60) - 3]);
- } else {
- sprintf(string, " (%cST)", "AECMPYHB"[- (tz / 60) - 4]);
- }
- }
- } else {
- sprintf(string + strlen(string), "+0000 (Local Time Zone Unknown)");
- }
- }
-
- /* init mail sending
- */
- static short mailinit(na_win *win, long *data)
- {
- encodewin *ew = (encodewin *) data;
- WindowPtr pwin = ew->w.winp.pwin;
- ControlHandle ctrlh;
- PCstr tstr[257], email[257];
-
- /* copy values from encode window */
- NAgetIText(pwin, iSubj, mwin->subj);
- NAgetIText(pwin, iEmailto, email);
- mwin->partsize = ew->partsize;
- mwin->useemail = ew->useemail;
- mwin->fspec = ew->fspec;
- mwin->ftype = ew->ftype;
- mwin->ofile = ew->ofile;
-
- /* copy desc file */
- mwin->dfile = NULL;
- if ((*ew->w.hTE)->teLength && (mwin->dfile = tmpfile()) != NULL) {
- copydesc(mwin->dfile, ew->w.hTE);
- }
-
- /* set procedures */
- win->taskp = mailtask;
- win->updatep = progressupdate;
- win->ctrlp = progressctrl;
- win->closep = mailclose;
-
- /* Customize Progress window, set up envelope & headers for email */
- prwin->percent = -1;
- NAgetDHandle(win->pwin, iCancel, &ctrlh);
- SetCTitle(ctrlh, "\pStop");
- NAmodalMenus(1);
- if (!mwin->useemail) {
- mwin->state = MS_ENCODE;
- } else {
- if (!tcpstart) NATCPinit(mytcpinit);
- NAsetIText(win->pwin, iWorkText, "\pLooking for MacTCP");
- mwin->state = MS_MACTCP;
-
- /* create envelope, get server */
- getICprefs(NULL, tstr, mwin->server);
- if (PtrToHand(C(tstr), &mwin->envelope, PCstrlen(tstr) + 1) != noErr
- || PtrAndHand(C(email), mwin->envelope, PCstrlen(email) + 1) != noErr) {
- if (mwin->envelope) DisposeHandle(mwin->envelope);
- return (NA_CLOSED);
- }
-
- /* create headers */
- if ((mwin->headers = NewHandle(1024)) == NULL) {
- DisposeHandle(mwin->envelope);
- return (NA_CLOSED);
- }
- HLock(mwin->headers);
- rfc822_date((char *) *mwin->headers);
- sprintf((char *) (*mwin->headers) + strlen((char *) (*mwin->headers)),
- "\r\nFrom: %s\r\nTo: %s\r\n", C(tstr), C(email));
- HUnlock(mwin->headers);
- SetHandleSize(mwin->headers, strlen((char *) (*mwin->headers)));
- }
-
- return (NA_NOTPROCESSED);
- }
-
- /* update the encode window
- */
- static short encodeupdate(na_win *win, Boolean newsize)
- {
- Rect btmp;
- ControlHandle ctrlh;
-
- /* draw double-line */
- NAgetDRect(win->pwin, iBar, &btmp);
- FrameRect(&btmp);
-
- /* draw disabled edittext boxes */
- NAgetDHandle(win->pwin, iLimit, &ctrlh);
- if (!GetCtlValue(ctrlh)) {
- NAhiliteDItem(win->pwin, iPartLimit, 255);
- }
- if (NAradioGet(win->pwin, iEmail, iSavefile) == iSavefile) {
- NAhiliteDItem(win->pwin, iEmailto, 255);
- }
-
- return (NATEupdatep(win, newsize));
- }
-
- /* select desc text
- */
- static short seldesctext(na_win *win)
- {
- win->activep = NATEactivep;
- win->idlep = NATEidlep;
- NATEactivep(win, true);
- ewin->nateon = true;
- SelIText(win->pwin, iDescEdit, 0, 0);
- TESetSelect(32767, 32767, twin->hTE);
- }
-
- /* encode control proc
- */
- static short encodectrl(na_win *win, Point p, short item,
- short mods, ControlHandle ctrlh)
- {
- short value;
- DialogPeek dpeek = (DialogPeek) win->pwin;
- char *scan;
- Boolean good;
- StandardFileReply reply;
- PCstr tstr[257];
-
- if (ctrlh == twin->vctrl) {
- return (NATEctrlp(win, p, item, mods, ctrlh));
- }
- switch (item) {
- case iOk:
- /* get part size */
- ewin->partsize = 0;
- NAgetDHandle(win->pwin, iLimit, &ctrlh);
- if (GetCtlValue(ctrlh)) {
- NAgetIText(win->pwin, iPartLimit, tstr);
- ewin->partsize = atol(C(tstr)) * 1000;
- }
- NAgetIText(win->pwin, iEmailto, tstr);
- ewin->useemail = NAradioGet(win->pwin, iEmail, iSavefile) == iEmail;
- if (ewin->useemail) {
- /* verify email address */
- if (!strchr(C(tstr), '@')) {
- yell("Invalid Email address, please re-enter");
- SelIText(win->pwin, iEmailto, 0, 32767);
- break;
- }
- } else {
- /* get output filename */
- PtoPCstrcpy(tstr, (char *) ewin->fspec.name);
- if (PCstrlen(tstr) > 23) {
- PCstrlen(tstr) = 23;
- SetClen(tstr);
- }
- strcat(C(tstr), ".mime");
- SetPlen(tstr);
- do {
- NAputFile(ewin->partsize ? "\pPart prefix" : "\pEmail file:",
- tstr, &reply);
- good = true;
- if (reply.sfGood
- && EqualString(reply.sfFile.name,
- ewin->fspec.name, true, false)) {
- good = false;
- yell("The output filename must be different from the input filename");
- }
- } while (!good);
- if (!reply.sfGood) break;
- ewin->ofile = reply.sfFile;
- }
- if (NAwindow(0, NA_DIALOGWINDOW | NA_TITLEBAR | NA_HASTASK
- | NA_USERESOURCE | NA_MODAL, NULL, progDLOG,
- (long *) win, sizeof (mailwin), mailinit) == NA_CLOSED) {
- warn("Not enough memory to proceed");
- break;
- }
- case iCancel:
- return (NA_REQCLOSE);
- case iEmail:
- case iSavefile:
- NAradioSet(win->pwin, iEmail, iSavefile, item);
- NAenableDItem(win->pwin, iEmailto, item == iEmail ? 1 : 0);
- NAhiliteDItem(win->pwin, iEmailto, item == iEmail ? 0 : 255);
- if (item == iEmail || dpeek->editField == iEmailto - 1) {
- SelIText(win->pwin, item == iEmail ? iEmailto : iSubj, 0, 32767);
- }
- break;
- case iLimit:
- SetCtlValue(ctrlh, value = !GetCtlValue(ctrlh));
- NAenableDItem(win->pwin, iPartLimit, value ? 1 : 0);
- NAhiliteDItem(win->pwin, iPartLimit, value ? 0 : 255);
- if (value || dpeek->editField == iPartLimit - 1) {
- SelIText(win->pwin, value ? iPartLimit : iSubj, 0, 32767);
- }
- break;
- case iDescEdit:
- case iSubj:
- case iEmailto:
- case iPartLimit:
- if (!ewin->nateon && dpeek->editField == iDescEdit - 1) {
- seldesctext(win);
- }
- break;
- }
- if (ewin->nateon && dpeek->editField != iDescEdit - 1) {
- win->activep = NULL;
- win->idlep = NULL;
- NATEactivep(win, false);
- ewin->nateon = false;
- }
-
- return (NA_NOTPROCESSED);
- }
-
- /* encode key proc
- */
- static short encodekey(na_win *win, long c, short mods)
- {
- if (!(mods & cmdKey)) {
- if (ewin->nateon && c != '\t' && c != '\n' && c != '\3' && c != '\033') {
- return (NATEkeyp(win, c, mods));
- }
- }
-
- return (NA_NOTPROCESSED);
- }
-
- /* menu proc for encode window
- */
- static short encodemenu(na_win *win, WORD menu, WORD item)
- {
- StandardFileReply descfile;
- MenuHandle mf = NAmenuh(mFile);
- short result = NA_NOTPROCESSED;
- short refnum;
- long size;
- Ptr text;
- Boolean success;
-
- switch (menu) {
- case 0:
- EnableItem(mf, iInsert);
- /* fall through */
- case mEdit:
- result = ewin->nateon ? NATEmenup(win, menu, item)
- : NAdialogMenu(win, menu, item);
- break;
- case mFile:
- if (item != iInsert) break;
- result = NA_PROCESSED;
- NAgetFile(NULL, 1, textList, &descfile);
- if (!descfile.sfGood) break;
- if (HOpen(descfile.sfFile.vRefNum, descfile.sfFile.parID,
- descfile.sfFile.name, fsRdPerm, &refnum) != noErr) {
- warn("Failed to open file");
- break;
- }
- text = NULL;
- success = GetEOF(refnum, &size) == noErr && (text = NewPtr(size)) != NULL
- && FSRead(refnum, &size, text) == noErr;
- if (success) {
- TEInsert(text, size, twin->hTE);
- TESelView(twin->hTE);
- NATEsetscroll(win, false, (Rect*) NULL, (Rect*) NULL);
- } else {
- warn("Failed to read file");
- }
- if (text) DisposPtr(text);
- FSClose(refnum);
- break;
- }
- if (menu != 0) DisableItem(mf, iInsert);
-
- return (result);
- }
-
- /* mouse proc for encode window
- */
- static short encodemouse(na_win *win, Point p, short type, short mods)
- {
- if (p.v >= twin->topoff && !ewin->nateon) seldesctext(win);
-
- return (NATEmousep(win, p, type, mods));
- }
-
- /* close the encode window
- */
- static short encodeclose(na_win *win)
- {
- NATEclosep(win);
-
- return (NA_CLOSED);
- }
-
- /* init the encode window
- */
- static short encodeinit(na_win *win, long *data)
- {
- StandardFileReply *sf = (StandardFileReply *) data;
- Rect rtmp, btmp;
- FontInfo finfo;
-
- /* copy data */
- ewin->fspec = sf->sfFile;
- ewin->ftype = sf->sfType;
-
- /* set sizing limits */
- NAgetDRect(win->pwin, iBar, &btmp);
- rtmp = win->pwin->portRect;
- win->minw = win->maxw = rtmp.right - rtmp.left;
- win->minh = btmp.bottom + 64;
- twin->topoff = btmp.bottom;
-
- /* init text area */
- TextFont(monaco);
- TextSize(9);
- GetFontInfo(&finfo);
- NATEinit(win, NATE_NOHSCROLL, 80 * finfo.widMax + 2, NULL, 0);
- ewin->nateon = 0;
- TextFont(0);
- TextSize(0);
-
- /* set control values */
- NAradioSet(win->pwin, iEmail, iSavefile, iSavefile);
- if (tcpstart < 0) NAhiliteDItem(win->pwin, iEmail, 255);
- NAenableDItem(win->pwin, iEmailto, 0);
- NAenableDItem(win->pwin, iPartLimit, 0);
- NAsetIText(win->pwin, iSubj, ewin->fspec.name);
- SelIText(win->pwin, iSubj, 0, 32767);
- SetWTitle(win->pwin, ewin->fspec.name);
- ShowWindow(win->pwin);
-
- /* set window procedures */
- win->updatep = encodeupdate;
- win->closep = encodeclose;
- win->keyp = encodekey;
- win->ctrlp = encodectrl;
- win->mousep = encodemouse;
- win->menup = encodemenu;
- win->idlep = NULL;
- win->activep = NULL;
-
- return (NA_NOTPROCESSED);
- }
-
- /* Encode procedure: first get a file, then open encode save window
- */
- static void do_encode(FSSpec *fspec, OSType ftype)
- {
- StandardFileReply infile;
-
- if (!fspec) {
- NAgetFile(NULL, -1, NULL, &infile);
- if (!infile.sfGood) return;
- } else {
- infile.sfFile = *fspec;
- infile.sfType = ftype;
- }
- NAwindow(NULL, NA_DIALOGWINDOW | NA_TITLEBAR | NA_GROWBOX | NA_USERESOURCE
- | NA_DEFBUTTON | NA_HASCONTROLS,
- NULL, sendDLOG, (long *) &infile, sizeof (encodewin), encodeinit);
- }
-
- /* Open a file via drag&drop
- */
- static short openfile(short message, FSSpec *fspec, FInfo *finfo)
- {
- if (message != appOpen) return (-1);
-
- /* open file */
- if (finfo->fdType == 'TEXT') {
- do_decode(fspec);
- } else {
- do_encode(fspec, finfo->fdType);
- }
-
- return (0);
- }
-
- #define hwinfo ((nate_win *)win)
-
- /* help close procedure
- */
- static short helpclose(na_win *win)
- {
- helpw = NULL;
-
- return (NATEclosep(win));
- }
-
- /* help window procedure
- */
- static short helpwindow(na_win *win, long *data)
- {
- Rect rtemp, vtemp;
- Handle h, hs;
- long len;
- TEHandle hTE;
-
- rtemp = win->pwin->portRect;
- vtemp = rtemp;
- vtemp.right = vtemp.left + (hwinfo->docwidth = 475);
- win->mousep = NATEmousep;
- win->idlep = NATEidlep;
- win->menup = NATEmenup;
- win->activep = NATEactivep;
- win->updatep = NATEupdatep;
- win->ctrlp = NATEctrlp;
- win->closep = helpclose;
- win->cursorRgn = NewRgn();
- hwinfo->vctrl = hwinfo->hctrl = NULL;
-
- TEAutoView(true, hTE = hwinfo->hTE = TEStylNew(&vtemp, &rtemp));
- h = GetResource('TEXT', helpTEXT);
- hs = GetResource('styl', helpSTYL);
- len = GetHandleSize(h);
- HLock(h);
- TEStylInsert(*h, len, (StScrpHandle) hs, hTE);
- HUnlock(h);
- TESetSelect(0, 0, hTE);
- hwinfo->lheight = TEGetHeight((*hTE)->nLines, 0, hTE) / (*hTE)->nLines;
- ShowWindow(helpw = win->pwin);
-
- return (NA_NOTPROCESSED);
- }
-
- /* Set the hostname: TCP callback
- */
- static void sethost(void *user, na_tcp s, short status, long size, char *data)
- {
- PCstr host[65];
- Rect box;
- na_win *win, **winh;
-
- /* first make sure our window still exists */
- for (winh = NAhead; winh && (*winh)->type != PREFWIN; winh = (*winh)->next);
- if (!winh || (*winh)->child != user) return;
- win = NAlockWindow((na_win **) user);
-
- /* check for errors */
- if (status != NATCP_connect) {
- warn("Failed to get hostname from MacTCP");
- } else {
- if (data[size - 1] == '.') --size;
- PCstrlen(host) = size;
- memcpy(C(host), data, size);
- NAsetIText((*winh)->pwin, iHost, host);
- SelIText((*winh)->pwin, iHost, 0, 32767);
- }
- prwin->percent = 100;
- progressupdate(win, false);
- NAunlockWindowh(winh, win);
- }
-
- /* if TCP is active, get hostname
- */
- static short settask(na_win *win)
- {
- if (tcpstart == 0 && !prwin->percent) {
- NAsetIText(win->pwin, iWorkText, "\pLooking for MacTCP");
- prwin->percent = 1;
- progressupdate(win, false);
- NATCPinit(mytcpinit);
- } else if (tcpstart == 1 && prwin->percent < 50) {
- NAsetIText(win->pwin, iWorkText, "\pLooking up Internet hostname");
- prwin->percent = 50;
- progressupdate(win, false);
- NATCPgethost(sethost, (void *) GetWRefCon(win->pwin));
- }
- progressupdate(win, false);
- if (tcpstart == -1) {
- warn("MacTCP not available");
- NAhiliteDItem((*win->parent)->pwin, iSet, 255);
- }
-
- return (tcpstart == -1 || prwin->percent == 100 ? NA_CLOSED : NA_NOTPROCESSED);
- }
-
- /* set the Internet host via MacTCP
- */
- static short setinit(na_win *win, long *data)
- {
- win->taskp = settask;
- win->updatep = progressupdate;
- win->closep = progressclose;
- NAmodalMenus(1);
-
- return (NA_NOTPROCESSED);
- }
-
- /* preference control procedure
- */
- static short prefsctrl(na_win *win, Point p, short item, short mods, ControlHandle ctrlh)
- {
- PCstr tmpstr[257];
- short encoding, extract_text, quit_finished, result = NA_NOTPROCESSED;
- ControlHandle ctrl;
- char *scan, *end;
- short changed, len, i, useic;
- static short prefitem[3] = { iHost, iEmailAddr, iMailServer };
-
- switch (item) {
- case iOk:
- HLock((Handle) mpack_prefs);
- changed = 0;
- encoding = NAradioGet(win->pwin, iAuto, iDouble) - iAuto;
- NAgetDHandle(win->pwin, iTextEncode, &ctrl);
- extract_text = GetCtlValue(ctrl);
- NAgetDHandle(win->pwin, iQuitFinish, &ctrl);
- quit_finished = GetCtlValue(ctrl);
- if (encoding != (*mpack_prefs)->encoding
- || extract_text != (*mpack_prefs)->extract_text
- || quit_finished != (*mpack_prefs)->quit_finished) {
- changed = 1;
- }
- if (changed) {
- (*mpack_prefs)->encoding = encoding;
- (*mpack_prefs)->extract_text = extract_text;
- (*mpack_prefs)->quit_finished = quit_finished;
- ChangedResource((Handle) mpack_prefs);
- changed = 0;
- }
- len = 1;
- scan = (*mpack_prefs)->internet_host;
- end = (char *) *mpack_prefs + GetHandleSize((Handle) mpack_prefs);
- for (i = 0; i < 3; ++i) {
- NAgetIText(win->pwin, prefitem[i], P(tmpstr));
- SetClen(tmpstr);
- len += PCstrlen(tmpstr);
- if (scan == end || strcmp(C(tmpstr), scan)) {
- changed = 1;
- }
- while (scan < end && *scan++);
- }
- if (changed) {
- HUnlock((Handle) mpack_prefs);
- /* update the preferences resource */
- SetHandleSize((Handle) mpack_prefs, sizeof (struct mpack_preferences)
- + len);
- HLock((Handle) mpack_prefs);
- scan = (*mpack_prefs)->internet_host;
- useic = icinst && ICBegin(icinst, icReadWritePerm) == noErr;
- for (i = 0; i < 3; ++i) {
- NAgetIText(win->pwin, prefitem[i], P(tmpstr));
- SetClen(tmpstr);
- strcpy(scan, C(tmpstr));
- scan += PCstrlen(tmpstr) + 1;
- if (i && useic) {
- ICSetPref(icinst, i == 1 ? kICEmail : kICSMTPHost,
- ICattr_no_change, (Ptr) P(tmpstr), PCstrlen(tmpstr) + 1);
- }
- }
- if (useic) ICEnd(icinst);
- ChangedResource((Handle) mpack_prefs);
- }
- HUnlock((Handle) mpack_prefs);
- case iCancel:
- result = NA_REQCLOSE;
- NAmodalMenus(0);
- break;
- case iAuto:
- case iData:
- case iSingle:
- case iDouble:
- NAradioSet(win->pwin, iAuto, iDouble, item);
- break;
- case iTextEncode:
- case iQuitFinish:
- SetCtlValue(ctrlh, !GetCtlValue(ctrlh));
- break;
- case iSet:
- NAwindow(0, NA_DIALOGWINDOW | NA_TITLEBAR | NA_HASTASK | NA_USERESOURCE
- | NA_MODAL | NA_CHILDWINDOW,
- NULL, progDLOG, NULL, sizeof (progresswin), setinit);
- break;
- }
-
- return (result);
- }
-
- /* update preferences dialog
- */
- static short prefsupdate(na_win *win, Boolean newsize)
- {
- Handle hn;
- Rect box;
- short type;
-
- /* draw disabled items */
- GetDItem(win->pwin, iEmailAddr, &type, &hn, &box);
- if (type == statText) NAhiliteDItem(win->pwin, iEmailAddr, 255);
- GetDItem(win->pwin, iMailServer, &type, &hn, &box);
- if (type == statText) NAhiliteDItem(win->pwin, iMailServer, 255);
-
- return (NA_NOTPROCESSED);
- }
-
- /* initialize preferences dialog
- */
- static short prefsinit(na_win *win, long *data)
- {
- PCstr tmpstr[257], eaddr[257];
- ControlHandle ctrl;
-
- win->type = PREFWIN;
- win->ctrlp = prefsctrl;
- win->menup = NAdialogMenu;
- win->updatep = prefsupdate;
- HLock((Handle) mpack_prefs);
- strcpy(C(tmpstr), (*mpack_prefs)->internet_host);
- HUnlock((Handle) mpack_prefs);
- SetPlen(tmpstr);
- NAsetIText(win->pwin, iHost, P(tmpstr));
- SelIText(win->pwin, iHost, 0, 32767);
- getICprefs(win, eaddr, tmpstr);
- NAsetIText(win->pwin, iEmailAddr, P(eaddr));
- NAsetIText(win->pwin, iMailServer, P(tmpstr));
- NAradioSet(win->pwin, iAuto, iDouble, (*mpack_prefs)->encoding + iAuto);
- NAsetIval(win->pwin, iTextEncode, (*mpack_prefs)->extract_text);
- NAsetIval(win->pwin, iQuitFinish, (*mpack_prefs)->quit_finished);
- if (tcpstart == -1) NAhiliteDItem(win->pwin, iSet, 255);
- NAmodalMenus(1);
- ShowWindow(win->pwin);
-
- return (NA_NOTPROCESSED);
- }
-
- /* Main menu procedure
- */
- static short mainmenu(na_win *win, WORD menuid, WORD itemno)
- {
- short status = NA_NOTPROCESSED;
- MenuHandle mh;
- PCstr version[32];
-
- switch (menuid) {
- case 0:
- NAenableMItem(mApple, iAbout);
- return (status);
- case mApple:
- if (itemno == iAbout) {
- CtoPCstrcpy(version, MPACK_VERSION);
- ParamText(P(version), NULL, NULL, NULL);
- return (NA_NOTPROCESSED);
- }
- break;
-
- case mFile:
- switch (itemno) {
- case iEncode:
- do_encode(NULL, 0);
- status = NA_PROCESSED;
- break;
-
- case iDecode:
- do_decode(NULL);
- status = NA_PROCESSED;
- break;
-
- case iClose:
- break;
-
- case iPrefs:
- status = NAwindow(0, NA_DIALOGWINDOW | NA_USERESOURCE
- | NA_MODAL | NA_DEFBUTTON | NA_TITLEBAR,
- NULL, prefsDLOG, (long *) NULL, 0, prefsinit);
- break;
-
- case iQuit:
- status = NA_REQCLOSEALL;
- break;
- }
- break;
-
- case mEdit:
- break;
-
- case mHelp:
- if (!helpw) {
- NAwindow(0, NA_USERESOURCE | NATEflags | NATE_READONLY | NA_SMARTSIZE,
- NULL, helpWIND, (long *) NULL, sizeof (nate_win), helpwindow);
- } else {
- SelectWindow(helpw);
- }
- break;
- }
- NAdisableMItem(mApple, iAbout);
-
- return (status);
- }
-
- /* make preferences folder/file
- * returns -1 on failure.
- */
- static short makepref()
- {
- Handle hpref = NULL, htmpl;
- long dirID;
- short vRefNum;
- char *scan, *end;
- PCstr dname[257];
- CInfoPBRec cpb;
- DirInfo *dp = &cpb.dirInfo;
- ParamBlockRec pb;
- VolumeParam *vp = &pb.volumeParam;
- FInfo finfo;
- static unsigned char pname[] = "\pprefs";
-
- /* set up pref folder storage */
- pfolder = (struct pref_folder *) NewPtr(sizeof (struct pref_folder));
- if (!pfolder) return (-1);
- end = scan = (char *) pfolder->prefs + sizeof (pfolder->prefs) - 1;
- *scan = '\0';
-
- /* get pref folder */
- if (FindFolder(kOnSystemDisk, kPreferencesFolderType,
- kCreateFolder, &vRefNum, &pfolder->fspec.parID) != noErr) {
- return (-1);
- }
-
- /* create subfolder, if needed */
- PtoPCstrcpy(dname, (char *) "\pMpack");
- (void) DirCreate(vRefNum, pfolder->fspec.parID, P(dname), &dirID);
-
- /* get mpack prefs folder info */
- dp->ioNamePtr = P(dname);
- dp->ioVRefNum = vRefNum;
- dp->ioFDirIndex = 0;
- dp->ioDrDirID = pfolder->fspec.parID;
- if (PBGetCatInfoSync(&cpb) != noErr) return (-1);
- pfolder->fspec.parID = dirID = dp->ioDrDirID;
- pfolder->fspec.vRefNum = vRefNum;
-
- /* generate pathname */
- dp->ioFDirIndex = -1;
- for (;;) {
- *--scan = ':';
- if (scan - (char *) pfolder->prefs < 1 + PCstrlen(dname)) return (-1);
- scan -= PCstrlen(dname);
- memcpy(scan, C(dname), PCstrlen(dname));
- if ((dp->ioDrDirID = dp->ioDrParID) == 2) break;
- if (PBGetCatInfoSync(&cpb) != noErr) return (-1);
- }
- vp->ioVolIndex = 0;
- vp->ioNamePtr = P(dname);
- vp->ioVRefNum = vRefNum;
- if (PBGetVInfoSync(&pb) != noErr) return (-1);
- *--scan = ':';
- if (scan - (char *) pfolder->prefs < 16 + PCstrlen(dname)) return (-1);
- PtoPCstrcpy(pfolder->prefs, (char *) P(dname));
- CtoPCstrcat(pfolder->prefs, scan);
-
- /* Get/Create preferences file */
- HCreateResFile(vRefNum, dirID, pname);
- if (ResError() == noErr) {
- HGetFInfo(vRefNum, dirID, pname, &finfo);
- finfo.fdType = 'pref';
- finfo.fdCreator = 'mPAK';
- HSetFInfo(vRefNum, dirID, pname, &finfo);
- hpref = GetResource('mPRF', prefsID);
- DetachResource(hpref);
- htmpl = GetResource('TMPL', IDnaID);
- DetachResource(htmpl);
- }
- pfolder->refnum = HOpenResFile(vRefNum, dirID, pname, fsRdWrPerm);
- if (pfolder->refnum < 0) return (-1);
- if (hpref) {
- AddResource(hpref, 'mPRF', prefsID, "\p");
- AddResource(htmpl, 'TMPL', IDnaID, "\pIDna");
- ReleaseResource(htmpl);
- } else {
- hpref = GetResource('mPRF', prefsID);
- }
- if (!hpref) return (-1);
- mpack_prefs = (struct mpack_preferences **) hpref;
-
- return (0);
- }
-
- /* cleanup shared resources
- */
- void maccleanup()
- {
- if (pfolder) {
- CloseResFile(pfolder->refnum);
- DisposPtr((Ptr) pfolder);
- }
- if (icinst) ICStop(icinst);
- if (tcpstart == 1) NATCPdone(120); /* give 2 seconds to go away */
- }
-
- main()
- {
- CursHandle cursH;
-
- if (NAinit(128, 2, openfile, mainmenu, 3, 1, 0, iClose) == 0) {
- /* set up preferences */
- if (makepref() < 0) {
- yell("Couldn't create preferences file");
- } else {
- /* set up internet config */
- if (ICStart(&icinst, 'mPAK') == noErr) {
- (void) ICFindConfigFile(icinst, 0, NULL);
- }
- /* save watch cursor */
- cursH = GetCursor(watchCursor);
- watch = **cursH;
- /* enter main loop, cleanup on exit */
- NAmainloop();
- maccleanup();
- }
- }
- }
-